*
* $Id$
*
* $Log: gneltu.F,v $
* Revision 1.1.1.1  2002/06/16 15:18:39  hristov
* Separate distribution  of Geant3
*
* Revision 1.1.1.1  1999/05/18 15:55:17  fca
* AliRoot sources
*
* Revision 1.1.1.1  1995/10/24 10:20:52  cernlib
* Geant
*
*
#include "geant321/pilot.h"
*CMZ :  3.21/02 29/03/94  15.41.29  by  S.Giani
*-- Author :
      SUBROUTINE GNELTU(X,PAR,IACT,SNEXT,SNXT,SAFE)
C
C     ****************************************************************
C     *                                                              *
C     *     Compute distance up to intersection with 'ELTU' volume,  *
C     *     from inside point X(1-3) along direction X(4-6).         *
C     *                                                              *
C     *     PAR    (input)  : volume parameters                      *
C     *     IACT   (input)  : action flag                            *
C     *       = 0   Compute SAFE only                                *
C     *       = 1   Compute SAFE, and SNXT only if SNEXT.gt.new SAFE *
C     *       = 2   Compute both SAFE and SNXT                       *
C     *       = 3   Compute SNXT only                                *
C     *     SNEXT  (input)  : see IACT = 1                           *
C     *     SNXT   (output) : distance to volume boundary            *
C     *     SAFE   (output) : shortest distance to any boundary      *
C     *                                                              *
C     *  ==>Called by : GNEXT,GTNEXT                                 *
C     *       Author  A.Solano                                       *
C     *                                                              *
C     ****************************************************************
C
#include "geant321/gconsp.inc"
C
      DIMENSION X(6),PAR(3)
#if !defined(CERNLIB_SINGLE)
      DOUBLE PRECISION SAFZ1,SAFZ2,SAFR,A2,B2,X0,Y0,A,B,D1,D2
      DOUBLE PRECISION X1,X2,X3,Y1,Y2,Y3
      DOUBLE PRECISION SZ,XZ,YZ,U,V,W,DISCR,SQDISC,TAU1,TAU2
#endif
C
      SNXT = BIG
      SAFZ1 = PAR(3)-X(3)
      SAFZ2 = PAR(3)+X(3)
C
      A2 = PAR(1)*PAR(1)
      B2 = PAR(2)*PAR(2)
C
      IF(IACT.LT.3)THEN
C
C        -----------------------------------
C        |  Compute safety-distance 'SAFE' |
C        -----------------------------------
C
         X0 = ABS(X(1))
         Y0 = ABS(X(2))
C
         A=PAR(1)
         B=PAR(2)
         X1=X0
         Y1=SQRT((A-X0)*(A+X0))*B/A
         Y2=Y0
         X2=SQRT((B-Y0)*(B+Y0))*A/B
         D1=(X1-X0)**2+(Y1-Y0)**2
         D2=(X2-X0)**2+(Y2-Y0)**2
         DO 1 I=1,8
            IF (B.LT.A) THEN
               X3=.5*(X1+X2)
               Y3=SQRT((A-X3)*(A+X3))*B/A
            ELSE
               Y3=.5*(Y1+Y2)
               X3=SQRT((B-Y3)*(B+Y3))*A/B
            END IF
            IF (D1.LT.D2) THEN
               X2=X3
               Y2=Y3
               D2=(X2-X0)**2+(Y2-Y0)**2
            ELSE
               X1=X3
               Y1=Y3
               D1=(X1-X0)**2+(Y1-Y0)**2
            END IF
    1    CONTINUE
    2    SAFR=SQRT(D1)-1.E-3
*
         SAFE = MIN(SAFZ1,SAFZ2,SAFR)
         IF(IACT.EQ.0)GOTO 99
         IF(IACT.EQ.1.AND.SNEXT.LT.SAFE)GOTO 99
C
      ENDIF
C
C        -----------------------------------
C        |  Compute vector-distance 'SNXT' |
C        -----------------------------------
C
C ....  First check Z
C
      IF(X(6).GT.0.)THEN
         SNXT = SAFZ1/X(6)
      ELSEIF(X(6).LT.0.)THEN
         SNXT = -SAFZ2/X(6)
      ENDIF
C
C ....  Then,if necessary,find the intersection of
C       the given ray(described by array X) whit
C       the cylinder.
C       Ray equation : X'(1-3) = X(1-3) + TAU*X(4-6)
C       Cylinder equation : x**2/a**2 + y**2/b**2 = 1
C       To obtain TAU,solve the quadratic equation
C       Ut**2 + 2Vt + W = 0
C
      SZ = SNXT
      XZ = X(1)+X(4)*SZ
      YZ = X(2)+X(5)*SZ
      IF((XZ*XZ/A2+YZ*YZ/B2).LE.1)GOTO 99
C
      U = X(4)*X(4)*B2+X(5)*X(5)*A2
      V = X(1)*X(4)*B2+X(2)*X(5)*A2
      W = X(1)*X(1)*B2+X(2)*X(2)*A2-A2*B2
      DISCR = V*V-U*W
      IF(DISCR.LT.0.)GOTO 99
      IF(U.EQ.0.)GOTO 99
      SQDISC = SQRT(DISCR)
      TAU1 = (-V+SQDISC)/U
      TAU2 = (-V-SQDISC)/U
C
C ....  Set SNXT to the smallest positive TAU
C
      IF(TAU1.LT.0.)THEN
         IF(TAU2.LT.0.)GOTO 99
         SNXT = TAU2
      ELSE
         SNXT = TAU1
         IF(TAU2.GT.0.0.AND.TAU2.LT.TAU1)THEN
            SNXT = TAU2
         ENDIF
      ENDIF
C
   99 END
